﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Collections.Specialized;

namespace Microhard.Core.Net
{
    public static class HttpReader
    {
        public static byte[] ReadImageUrl(this string url)
        {
            byte[] rtn = null;
            WebClient wc = new WebClient();
            try
            {
                rtn = wc.DownloadData(url);
            }
            catch (Exception ex)
            {
                Log.Error("ReadImageUrl错误", ex);
            }
            return rtn;
        }

        public static string HttpGet(string URI)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URI);
            System.Net.WebResponse resp = null;
            resp = req.GetResponse();
            if (resp != null)
            {
                System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
                return sr.ReadToEnd().Trim();
            }
            return null;
        }

        public static byte[] HttpGet(string URI, out string fileType)
        {
            byte[] result = null;
            fileType = string.Empty;
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URI);
            System.Net.WebResponse resp = null;
            try
            {
                resp = req.GetResponse();
                fileType = resp.ContentType;
            }
            catch (Exception ex)
            {
                Log.Error("HttpGet", ex);
            }
            finally
            {
                if (resp != null)
                {
                    var stream = resp.GetResponseStream();
                    result = new byte[stream.Length];
                    stream.Read(result, 0, result.Length);
                    // 设置当前流的位置为流的开始
                    stream.Seek(0, SeekOrigin.Begin);

                }
            }
            return result;
        }

        public static string HttpGet(string URI, ref CookieContainer cookie)
        {
            ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                return true;
            };

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URI);
            req.CookieContainer = cookie;
            req.AllowAutoRedirect = false;
            System.Net.WebResponse resp = req.GetResponse();
            System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
            return sr.ReadToEnd().Trim();
        }

        public static Stream HttpGetStream(string URI, ref CookieContainer cookie)
        {
            ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                return true;
            };

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URI);
            req.CookieContainer = cookie;
            System.Net.WebResponse resp = req.GetResponse();
            return resp.GetResponseStream();
        }


        public static string HttpPostWithUTF8(string URI, string Parameters)
        {
            ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                return true;
            };
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URI);

            //Add these, as we're doing a POST
            req.ContentType = "application/json; encoding=utf-8";
            req.Method = "POST";
            //We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value&
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(Parameters);
            req.ContentLength = bytes.Length;
            System.IO.Stream os = req.GetRequestStream();
            os.Write(bytes, 0, bytes.Length); //Push it out there
            os.Close();
            System.Net.WebResponse resp = req.GetResponse();
            if (resp == null) return null;
            System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
            var html = sr.ReadToEnd().Trim();
            return html;
        }

        public static string HttpPost(string URI, string Parameters)
        {
            ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                return true;
            };
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URI);

            //Add these, as we're doing a POST
            req.ContentType = "application/x-www-form-urlencoded";
            req.Method = "POST";
            //We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value&
            byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
            req.ContentLength = bytes.Length;
            System.IO.Stream os = req.GetRequestStream();
            os.Write(bytes, 0, bytes.Length); //Push it out there
            os.Close();
            System.Net.WebResponse resp = req.GetResponse();
            if (resp == null) return null;
            System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
            var html = sr.ReadToEnd().Trim();
            return html;
        }


        public static string HttpPost(string URI, string Parameters, ref CookieContainer cookie)
        {
            ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                return true;
            };
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URI);
            req.CookieContainer = cookie;

            //Add these, as we're doing a POST
            req.ContentType = "application/x-www-form-urlencoded";
            req.Method = "POST";
            //We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value&
            byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
            req.ContentLength = bytes.Length;
            System.IO.Stream os = req.GetRequestStream();
            os.Write(bytes, 0, bytes.Length); //Push it out there
            os.Close();
            System.Net.WebResponse resp = req.GetResponse();
            if (resp == null) return null;
            System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
            var html = sr.ReadToEnd().Trim();
            return html;
        }

        public static string HttpGetFakeAsChrome(string URI, string Referer, ref CookieContainer cookie)
        {
            ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                return true;
            };

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URI);
            req.CookieContainer = cookie;
            req.Referer = Referer;
            //Add these, as we're doing a POST
            req.ContentType = "application/x-www-form-urlencoded";
            req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            req.Headers["Accept-Encoding"] = "gzip,deflate,sdch";
            req.Headers["Accept-Language"] = "zh-CN,zh;q=0.8";
            req.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36";

            var resp = req.GetResponse() as HttpWebResponse;
            if (resp != null)
            {
                foreach (var c in resp.Cookies.OfType<Cookie>())
                {
                    cookie.Add(c);
                }
            }
            System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
            return sr.ReadToEnd().Trim();
        }

        public static string HttpPostWith302(string URI, string Parameters, string Referer, ref CookieContainer cookie)
        {
            //使用httpwebrequest模拟chrome可以解决ASPXAUTH cookie获取不到的问题,这样就可以使用cookie请求其他页面
            ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                return true;
            };
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URI);
            req.CookieContainer = cookie;
            req.Referer = Referer;
            //Add these, as we're doing a POST
            req.ContentType = "application/x-www-form-urlencoded";
            req.Method = "POST";
            req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
            req.Headers["Accept-Encoding"] = "gzip,deflate,sdch";
            req.Headers["Accept-Language"] = "zh-CN,zh;q=0.8";
            req.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36";
            req.AllowAutoRedirect = false;
            //We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value&
            byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
            req.ContentLength = bytes.Length;
            System.IO.Stream os = req.GetRequestStream();
            os.Write(bytes, 0, bytes.Length); //Push it out there
            os.Close();
            var resp = req.GetResponse() as HttpWebResponse;
            if (resp != null)
            {
                if (resp.StatusCode == HttpStatusCode.Redirect ||
        resp.StatusCode == HttpStatusCode.MovedPermanently)
                {
                    foreach (var c in resp.Cookies.OfType<Cookie>())
                    {
                        cookie.Add(c);
                    }
                    string newUrl = Referer + resp.Headers["Location"];
                    string redhtml = HttpGetFakeAsChrome(newUrl, Referer, ref cookie);
                    return redhtml;
                }
            }
            System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
            var html = sr.ReadToEnd().Trim();
            return html;
        }

        public static string HttpPost(string URI, string Parameters, string Referer, ref CookieContainer cookie)
        {
            ServicePointManager.ServerCertificateValidationCallback = delegate(object s, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                return true;
            };
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URI);
            req.CookieContainer = cookie;
            req.Referer = Referer;
            //Add these, as we're doing a POST
            req.ContentType = "application/x-www-form-urlencoded";
            req.Method = "POST";
            req.Accept = "Accept: text/html, application/xhtml+xml, */*";
            req.Headers["Accept-Encoding"] = "gzip, deflate";
            req.Headers["Accept-Language"] = "zh-CN";
            req.UserAgent = "User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)";
            req.AllowAutoRedirect = true;
            //We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value&
            byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
            req.ContentLength = bytes.Length;
            System.IO.Stream os = req.GetRequestStream();
            os.Write(bytes, 0, bytes.Length); //Push it out there
            os.Close();
            System.Net.WebResponse resp = req.GetResponse();
            if (resp == null) return null;
            System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
            var html = sr.ReadToEnd().Trim();
            return html;
        }

        public static string HttpUploadFile(string url, string file, string paramName, string contentType, NameValueCollection nvc, ref CookieContainer cookie)
        {
            string result = string.Empty;
            string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
            byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

            HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
            wr.ContentType = "multipart/form-data; boundary=" + boundary;
            wr.Method = "POST";
            wr.KeepAlive = true;
            wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
            wr.CookieContainer = cookie;

            Stream rs = wr.GetRequestStream();

            if (nvc != null)
            {
                string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
                foreach (string key in nvc.Keys)
                {
                    rs.Write(boundarybytes, 0, boundarybytes.Length);
                    string formitem = string.Format(formdataTemplate, key, nvc[key]);
                    byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                    rs.Write(formitembytes, 0, formitembytes.Length);
                }
                rs.Write(boundarybytes, 0, boundarybytes.Length);
            }

            string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
            //去除地址路径
            string[] fileArr = file.Split(new char[] { '\\' });
            string filename = fileArr[fileArr.Length - 1];

            string header = string.Format(headerTemplate, paramName, filename, contentType);
            byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
            rs.Write(headerbytes, 0, headerbytes.Length);

            FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
            byte[] buffer = new byte[4096];
            int bytesRead = 0;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                rs.Write(buffer, 0, bytesRead);
            }
            fileStream.Close();

            byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
            rs.Write(trailer, 0, trailer.Length);
            rs.Close();

            WebResponse wresp = null;
            try
            {
                wresp = wr.GetResponse();
                Stream stream2 = wresp.GetResponseStream();
                StreamReader reader2 = new StreamReader(stream2);

                result = reader2.ReadToEnd();
            }
            catch (Exception ex)
            {
                if (wresp != null)
                {
                    wresp.Close();
                    wresp = null;
                }
            }
            finally
            {
                wr = null;
            }

            return result;
        }

        public static string HttpUploadFile(string url, string fileName, byte[] file, string paramName, string contentType, NameValueCollection nvc, ref CookieContainer cookie)
        {
            string result = string.Empty;
            string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
            byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

            HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
            wr.ContentType = "multipart/form-data; boundary=" + boundary;
            wr.Method = "POST";
            wr.KeepAlive = true;
            wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
            wr.CookieContainer = cookie;

            Stream rs = wr.GetRequestStream();

            if (nvc != null)
            {
                string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
                foreach (string key in nvc.Keys)
                {
                    rs.Write(boundarybytes, 0, boundarybytes.Length);
                    string formitem = string.Format(formdataTemplate, key, nvc[key]);
                    byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                    rs.Write(formitembytes, 0, formitembytes.Length);
                }
                rs.Write(boundarybytes, 0, boundarybytes.Length);
            }

            string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";

            string header = string.Format(headerTemplate, paramName, fileName, contentType);
            byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
            rs.Write(headerbytes, 0, headerbytes.Length);

            //将图片字节写入到response stream 中
            rs.Write(file, 0, file.Length);

            byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
            rs.Write(trailer, 0, trailer.Length);
            rs.Close();

            WebResponse wresp = null;
            try
            {
                wresp = wr.GetResponse();
                Stream stream2 = wresp.GetResponseStream();
                StreamReader reader2 = new StreamReader(stream2);

                result = reader2.ReadToEnd();
            }
            catch (Exception ex)
            {
                if (wresp != null)
                {
                    wresp.Close();
                    wresp = null;
                }
            }
            finally
            {
                wr = null;
            }

            return result;
        }

        public static string HttpUploadFile(string url, string fileName, byte[] file, string paramName, string contentType, NameValueCollection nvc)
        {
            string result = string.Empty;
            string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
            byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

            HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
            wr.ContentType = "multipart/form-data; boundary=" + boundary;
            wr.Method = "POST";
            wr.KeepAlive = true;
            wr.Credentials = System.Net.CredentialCache.DefaultCredentials;

            Stream rs = wr.GetRequestStream();

            if (nvc != null)
            {
                string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
                foreach (string key in nvc.Keys)
                {
                    rs.Write(boundarybytes, 0, boundarybytes.Length);
                    string formitem = string.Format(formdataTemplate, key, nvc[key]);
                    byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                    rs.Write(formitembytes, 0, formitembytes.Length);
                }
                rs.Write(boundarybytes, 0, boundarybytes.Length);
            }

            string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";

            string header = string.Format(headerTemplate, paramName, fileName, contentType);
            byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
            rs.Write(headerbytes, 0, headerbytes.Length);

            //将文件字节写入到response stream 中
            rs.Write(file, 0, file.Length);

            byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
            rs.Write(trailer, 0, trailer.Length);
            rs.Close();

            WebResponse wresp = null;
            try
            {
                wresp = wr.GetResponse();
                Stream stream2 = wresp.GetResponseStream();
                StreamReader reader2 = new StreamReader(stream2);

                result = reader2.ReadToEnd();
            }
            catch (Exception ex)
            {
                if (wresp != null)
                {
                    wresp.Close();
                    wresp = null;
                }
                Log.Error("HttpUploadFile", ex);
            }
            finally
            {
                wr = null;
            }

            return result;
        }
    }
}
